//
//  App+UUID.swift
//  PHP Monitor
//
//  Created by Nico Verbruggen on 01/12/2025.
//  Copyright © 2025 Nico Verbruggen. All rights reserved.
//

import Foundation

struct Api {
    /**
    How long a API ID (uuid) is valid.

    Currently set to this length to accomodate potential failures
    for the update check.
    */
    static let uuidValidityDuration: TimeInterval = .hours(36)

    static let uuidKey = "api.uuid"
    static let uuidTimestampKey = "api.uuid.timestamp"
}

extension App {
    /**
     Returns a unique UUID that automatically refreshes every 36 hours.
     It is used to more accurately throttle API requests for a given IP,
     since multiple users could be coming from one residential/business IP.

     - Important: This UUID is NOT used for tracking.
       It is used for legitimate purposes only.
       Read more below to find out how this UUID is used.

     How it is used:

     - Allows identifying which IP addresses might be throttled too quickly
       (example: many requests with the same IP, but different unique UUIDs)

     - Allows counting how many unique users checked for updates in 24 hours
       (example: previous assumption was: 1 IP = 1 user; not always true!)

     The UUID is stored in UserDefaults and regenerated when it has expired.
     Because I only use this for user counting, the ID is reset after 36 hours.
     */
    func getApiId() -> String {
        let defaults = UserDefaults.standard

        // Check if we have a stored UUID and timestamp
        if let storedUUID = defaults.string(forKey: Api.uuidKey),
           let storedTimestamp = defaults.object(forKey: Api.uuidTimestampKey) as? Date {

            // Check if the UUID is still valid (less than X hours old)
            if Date().timeIntervalSince(storedTimestamp) < Api.uuidValidityDuration {
                return storedUUID
            }
        }

        // Generate a new UUID if we don't have one or it's expired
        return regenerate()
    }

    /**
     Regenerates a UUID for a given duration.
     */
    private func regenerate() -> String {
        let newUUID = UUID().uuidString
        let defaults = UserDefaults.standard

        defaults.set(newUUID, forKey: Api.uuidKey)
        defaults.set(Date(), forKey: Api.uuidTimestampKey)

        return newUUID
    }
}
